local debug = require "debug"



----------------------------------------------------------------------------------------------------------------------------------------
--初始化参数
local gallop={
	name = 'Gallop';
	init_funcs = {};
	presave_funcs = {};
	load_funcs = {};
};
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--创建表和创建元表
function gallop:new (o)
	print( 'Init Gallop Envs' )
	o = o or {};
	self.__index = self;
	setmetatable(o,self)
	return o;
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--初始化程序：初始化，新建文档时候调用
function gallop:init ()
	print( "Gallop Init Fun" );
	for k,v in pairs( self.init_funcs ) do
		v();
	end
	debug.sethook(self.trace, "l")
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--初始化程序：初始化，新建文档时候调用
function gallop:init_project ()
	--print( "Gallop Init Fun" );
	for k,v in pairs( self.init_funcs ) do
		v();
	end
	debug.sethook(self.trace, "l")
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--初始化程序：初始化，打开文档时候调用
function gallop:postload ()
	--print( "Gallop Init" );
	for k,v in pairs( self.load_funcs ) do
		--print( k )
		local sta,res = pcall(v);
		if sta == false then
			print( k, sta,res );
		end
	end
	debug.sethook(self.trace, "l")
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--退出程序：保存文档时候调用
function gallop:presave ()
	--print( "Gallop Presave" );
	for k,v in pairs( self.presave_funcs ) do
		v();
	end
end
----------------------------------------------------------------------------------------------------------------------------------------


----------------------------------------------------------------------------------------------------------------------------------------
--打包所有参数
function gallop:get_settings_str()
	local str = '';
	for k,v in pairs(getmetatable(self)) do
		 if type(k) == "string" and (type(v)=="number" or type(v)=="boolean") then
			str = str .. k .. '=' .. tostring(v) .. '; \n'
		 end
		 
		 if type(k) == "string" and k ~= 'init_strs' and ( type(v)=="string"  ) then
			str = str .. k .. '= [[' .. tostring(v) .. ']]; \n'
		 end
	end
	for k,v in pairs(self) do
		 if type(k) == "string" and (type(v)=="number" or type(v)=="boolean") then
			str = str .. k .. '=' .. tostring(v) .. '; \n'
		 end
		 
		 if type(k) == "string" and k ~= 'init_strs' and ( type(v)=="string"  ) then
			str = str .. k .. '= [[' .. tostring(v) .. ']]; \n'
		 end
	end
 	--print(str)
	--str = str:gsub("\n\r", "\n")
	return str;
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--设置所有参数
function gallop:set_settings_str(str)
	--print(str)
	local f = assert(load(' return {' .. str ..'}'))
	local sets = f();
	for k,v in pairs(sets) do
		self[k] = v;
	end
end
----------------------------------------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------------------------------------
--trace
function gallop.trace (event, line)
    --if GetSuspendFlag()==true then 
	--Gallop:SetSuspendFlag(false);
	--error("Stop solver");
	--return;
    --end
    if GetStopFlag()==true 
	--and GetSuspendFlag() ==true
	then
        local s = debug.getinfo(2).source
        -- print( s .. ":" .. line )
	--print("Stop solver")
	error("Stop solver")
    end
end
----------------------------------------------------------------------------------------------------------------------------------------

function gallop.traceback(err)

   errStr="";

   if  GetStopFlag()==true then
	return   
   end;
   

   for level = 1, math.huge do
        local info = debug.getinfo(level, "nSlf")
        if not info then break end
        if info.what == "C" then -- is a C function?
            print(level, "C function")
        else
            print(string.format("%d\t[%s] : %d", level, info.source, info.currentline))
        end
    end
    print("LUA ERROR: " .. tostring(err))
    errStr = err;
    for  level = 2, math.huge do
        local info = debug.getinfo(level, "nSlf")
	-- print("info:",info)
        if not info then break end
	 local source = info.source
         if info.what ~= "C" then -- is a C function?
	     longpath = string.match(source, "@(.+)")
	     path,linenum,msg = string.match(err, "(.+):([0-9]+):(.+)")
	     print(longpath)
	     if longpath~=nil then
		 errStr = (longpath)..":"..(info.currentline)..":".. ( msg or (" "..err) )
		 break;
	     end
	  end
    end
    
    --self.errStr = errStr;
    --error(errStr)
    --print("ERROR: " .. errStr)
    --return errStr;
end 

function gallop:do_file(filepath)
	--print(filepath);
	local f = assert(loadfile(filepath))
	debug.sethook(self.trace, "l")	
	local status = xpcall(f, self.traceback)
	--debug.sethook()

	if status==false then
		--print(err)
		error(errStr)
	end
	--print('err:',errStr)
	--if type(errStr) == 'string' and errStr ~= "" then
	    --error(errStr)
	--end
end
--function gallop:do_file(filepath)
	--print(filepath)
	--local f = assert(loadfile(filepath))
	--debug.sethook(self.trace, "l")
	--local errStr = xpcall(f, self.traceback)
--end

return gallop;